<?php
/**
 * This file is part of the Wicked package.
 *
 * Copyright Aymeric Assier <aymeric.assier@gmail.com>
 *
 * For the full copyright and license information, please view the Licence.txt
 * file that was distributed with this source code.
 */
namespace wicked;

use wicked\process\Runnable;
use wicked\process\Initializer;
use wicked\process\Router;
use wicked\process\Builder;
use wicked\core\Event;
use wicked\core\Session;

/**
 * God Controller
 *
 * @author Aymeric Assier <aymeric.assier@gmail.com>
 * @date 2012-10-05
 * @version 1.0
 */
class App
{

    /** @var array */
    protected static $config = [
        'app' => [
            'name' => 'WickedApp',
            'mode' => 'dev', // 'dev' or 'prod'
            'ip_dev' => '127.0.0.1'
        ],
        'default' => [
            'controller' => 'Home',
            'layout' => 'default',
            'route' => '(:controller)?/(:action)?/(:args)?',
        ],
        'folder' => [
            'controller' => 'app\controllers',
            'module' => 'app\modules',
            'layout' => 'app/views/layouts',
            'template' => 'app/views/templates',
            'block' => 'app/views/blocks',
            'public' => 'app/public',
        ]
    ];

    /** @var array */
    protected static $log = [];

    /** @var \wicked\core\Initializer */
    public $initializer;

    /** @var \wicked\core\Router */
    public $router;

    /** @var \wicked\core\Builder */
    public $builder;


    /**
     * Constructor with user config
     */
    public function __construct()
    {
        // set app token
        $this->set('app::token', sha1(APP_URL));

        // set processes
        $this->initializer = new Initializer();
        $this->router = new Router();
        $this->builder = new Builder();
    }


    /**
     * Run the whole web application
     */
    public function run()
    {
        // start app
        Event::fire('app.start');

        // scope 'dev' : die if not allowed
        if(config('app::mode') == 'dev' and !in_array($_SERVER['REMOTE_ADDR'], (array)config('app::ip_dev')))
        {
            header('HTTP/1.1 503 Service Temporarily Unavailable');
            die();
        }

        // open session
        Session::open();

        // run processes
        if($this->initializer instanceof Runnable)
            $this->initializer->run();

        if($this->router instanceof Runnable)
            $this->router->run();

        if($this->builder instanceof Runnable)
            $this->builder->run();

        // close session
        Session::close();

        // end app
        Event::fire('app.end');
    }


    /**
     * Set config
     * @param $key
     * @param $value
     */
    public function set($key, $value)
    {
        list($repository, $index) = explode('::', $key);
        static::$config[$repository][$index] = $value;
    }


    /**
     * Config shortcut accessor
     * @static
     * @param string $key
     * @return mixed
     */
    public static function config($key)
    {
        list($repository, $index) = explode('::', $key);

        if(isset(static::$config[$repository][$index]))
            return static::$config[$repository][$index];

        return null;
    }


    /**
     * Set log message
     * @static
     * @param null $message
     * @return array
     */
    public static function log($message = null)
    {
        if(is_null($message))
            return self::$log;
        else
            self::$log[] = $message;
    }

}